﻿using System;
using System.Collections.Generic;
using System.Text;
using RayD.Repository.Entites.SystemModule;
using RayD.Core;
using RayD.Repository;
using Dapper;
using System.Data;
using System.Linq;
using Newtonsoft.Json.Linq;
using RayD.Repository.Core;

namespace RayD.App.SystemModule
{
    public class PostApp
    {

        #region 构造函数注入
        private IRepository BaseRepository;
        private DepartmentApp _Department;
        private ManaframeApp _manaframe;
        public PostApp(IRepository repository, ManaframeApp manaframe, DepartmentApp Department)
        {
            this.BaseRepository = repository;
            this._manaframe = manaframe;
            this._Department = Department;
        }
        #endregion

        #region 获取数据

        /// <summary>
        /// 获取列表数据
        /// </summary>
        /// <param name="queryJson">查询条件</param>
        /// <returns></returns>
        public IEnumerable<PostEntity> GetList(string queryJson)
        {
            var expression = LinqExtensions.True<PostEntity>();

            var queryParam = queryJson.ToJObject();
            if (!queryParam["B_ManaframeId"].IsEmpty())
            {
                expression = expression.And(c => c.B_ManaframeId == queryParam["B_ManaframeId"].ToString());
            }
            if (!queryParam["B_DepartmentId"].IsEmpty())
            {
                expression = expression.And(c => c.B_DepartmentId == queryParam["B_DepartmentId"].ToString());
            }
            if (!queryParam["B_Name"].IsEmpty())
            {
                expression = expression.And(c => c.B_Name.Contains(queryParam["B_Name"].ToString()));
            }
            if (!queryParam["B_EnCode"].IsEmpty())
            {
                expression = expression.And(c => c.B_EnCode.Contains(queryParam["B_EnCode"].ToString()));
            }
            if (!queryParam["B_CreateDate"].IsEmpty())
            {
                expression = expression.And(c => c.B_CreateDate >= queryParam["B_CreateDate"][0].ToDate() && c.B_CreateDate <= queryParam["B_CreateDate"][1].ToDate());
            }
            /*关联架构*/
            var userInfo = AuthenticationHelper.LoginUserInfo;
            if (!userInfo.isSystem)
            {
                var manaframeIds = _manaframe.GetSubNodes(userInfo.manaframeId);
                expression = expression.And(c => manaframeIds.IndexOf(c.B_ManaframeId) >= 0);
            }
            return BaseRepository.IQueryable(expression);
        }
        /// <summary>
        /// 获取分页列表数据
        /// </summary>
        /// <param name="queryJson">查询条件</param>
        /// <param name="pagination">分页参数</param>
        /// <returns></returns>
        public IEnumerable<PostEntity> GetPageList(string queryJson, Pagination pagination)
        {
            var expression = LinqExtensions.True<PostEntity>();
            var queryParam = queryJson.ToJObject();
            if (!queryParam["B_ManaframeId"].IsEmpty())
            {
                expression = expression.And(c => c.B_ManaframeId == queryParam["B_ManaframeId"].ToString());
            }
            if (!queryParam["B_DepartmentId"].IsEmpty())
            {
                expression = expression.And(c => c.B_DepartmentId == queryParam["B_DepartmentId"].ToString());
            }
            if (!queryParam["B_Name"].IsEmpty())
            {
                expression = expression.And(c => c.B_Name.Contains(queryParam["B_Name"].ToString()));
            }
            if (!queryParam["B_EnCode"].IsEmpty())
            {
                expression = expression.And(c => c.B_EnCode.Contains(queryParam["B_EnCode"].ToString()));
            }
            if (!queryParam["B_CreateDate"].IsEmpty())
            {
                expression = expression.And(c => c.B_CreateDate >= queryParam["B_CreateDate"][0].ToDate() && c.B_CreateDate <= queryParam["B_CreateDate"][1].ToDate());
            }
            /*关联架构*/
            var userInfo = AuthenticationHelper.LoginUserInfo;
            if (!userInfo.isSystem)
            {
                var manaframeIds = _manaframe.GetSubNodes(userInfo.manaframeId);
                expression = expression.And(c => manaframeIds.IndexOf(c.B_ManaframeId) >= 0);
            }
            var list = this.BaseRepository.IQueryable(expression)
                        .OrderBy(pagination.sidx, pagination.sord)
                        .ToTree();
            /***********************分页处理*********************/
            var rowsData = list.Skip(pagination.pageSize * (pagination.currentPage - 1)).Take(pagination.pageSize);
            pagination.records = list.Count();

            return rowsData;
        }
        /// <summary>
        /// 获取岗位本身和子岗位的id
        /// </summary>
        /// <param name="B_ManaframeId">组织ID</param>
        /// <param name="B_ParentId">父级ID</param>
        /// <returns></returns>
        [Caching]
        public virtual List<string> GetSubNodes(string B_ManaframeId, string B_ParentId)
        {
            if (B_ParentId.IsEmpty() || B_ManaframeId.IsEmpty())
            {
                return new List<string>();
            }
            List<string> res = new List<string>();
            res.Add(B_ParentId);

            var expression = LinqExtensions.True<PostEntity>().And(c => c.B_EnabledMark == EnabledMark.Enabled);
            if (!B_ManaframeId.IsEmpty())
            {
                expression = expression.And(c => c.B_ManaframeId == B_ManaframeId);
            }
            var list = BaseRepository.IQueryable(expression);
            list.ToTree(B_ParentId).GetSubNodes(res);
            return res;
        }
        /// <summary>
        /// 获取树型列表数据
        /// </summary>
        /// <param name="account">登录账户(缓存键)</param>
        /// <param name="B_ManaframeId">组织架构主键</param>
        /// <param name="B_DepartmentId">部门主键</param>
        /// <param name="isDeep">是否深度获取</param>
        /// <returns></returns>
        [Caching]
        public virtual List<PostEntity> GetTreeList(string account, string B_ManaframeId, string B_DepartmentId, bool isDeep)
        {
            var list = this.GetListByManaDepId(account, B_ManaframeId, B_DepartmentId, isDeep);
            return list.ToTree().ToList();
        }
        /// <summary>
        /// 根据架构Id及部门Id获取列表数据
        /// </summary>
        /// <param name="account">登录账户(缓存键)</param>
        /// <param name="B_ManaframeId">组织架构主键</param>
        /// <param name="B_DepartmentId">部门主键</param>
        /// <param name="isDeep">是否深度获取</param>
        /// <returns></returns>
        [Caching]
        public virtual List<PostEntity> GetListByManaDepId(string account, string B_ManaframeId, string B_DepartmentId, bool isDeep)
        {
            StringBuilder strSql = new StringBuilder(200);
            strSql.Append(@"Select 
                                t.B_PostId
,t.B_ParentId
,t.B_Name
,t2.B_FullName DepartmentName
,t.B_EnCode
,t.B_ManaframeId
,t.B_DepartmentId
,t.B_EnabledMark
,t.B_Description
,t.B_CreateDate
,t.B_CreateUserId
,t.B_CreateUserName
,t.B_ModifyDate
,t.B_ModifyUserId
,t.B_ModifyUserName
                From BASE_POST t
                LEFT JOIN BASE_DEPARTMENT t2 ON (t.B_DepartmentId = t2.B_DepartmentId)
                WHERE t.B_EnabledMark = 1
            ");

            List<PostEntity> resList = new List<PostEntity>();

            //是否深度查询
            if (isDeep)
            {
                var list = BaseRepository.FindList<PostEntity>(strSql.ToString())
                    .OrderBy(c => c.B_ManaframeId)
                    .AsList();
                list.ForEach(c => c.B_Name = $"【{c.DepartmentName}】{c.B_Name}");

                //只有组织传入，获取包括子组织下所有岗位
                if (!B_ManaframeId.IsEmpty() && B_DepartmentId.IsEmpty())
                {
                    var manaNodes = _manaframe.GetSubNodes(B_ManaframeId);

                    for (int i = 0; i < manaNodes.Length(); i++)
                    {
                        resList.AddRange(list.FindAll(c => c.B_ManaframeId == manaNodes[i]));
                    }
                }
                //有部门传入，获取包括子组织、子部门下所有岗位
                else if (!B_DepartmentId.IsEmpty())
                {
                    var depNodes = _Department.GetSubNodes(B_ManaframeId, B_DepartmentId);

                    for (int i = 0; i < depNodes.Length(); i++)
                    {
                        resList.AddRange(list.FindAll(c => c.B_DepartmentId == depNodes[i]));
                    }
                }
                else
                {
                    resList = list;
                }
            }
            else
            {
                // 虚拟参数
                var dp = new DynamicParameters(new { });
                if (!B_ManaframeId.IsEmpty())
                {
                    dp.Add("B_ManaframeId", B_ManaframeId, DbType.String);
                    strSql.Append(" And t.B_ManaframeId = @B_ManaframeId ");
                }
                if (!B_DepartmentId.IsEmpty())
                {
                    dp.Add("B_DepartmentId", B_DepartmentId, DbType.String);
                    strSql.Append(" And t.B_DepartmentId = @B_DepartmentId ");
                }
                resList = BaseRepository.FindList<PostEntity>(strSql.ToString(), dp).AsList();
            }
            /*关联架构*/
            var userInfo = AuthenticationHelper.LoginUserInfo;
            if (!userInfo.isSystem)
            {
                var manaframeIds = _manaframe.GetSubNodes(userInfo.manaframeId);
                resList = resList.FindAll(c => manaframeIds.IndexOf(c.B_ManaframeId) >= 0);
            }
            return resList;
        }
        #endregion

        #region 提交数据
        /// <summary>
        /// 保存实体(新增,编辑)
        /// </summary>
        /// <param name="formEntity"></param>
        [RemoveCache]
        public virtual (bool, string) SaveForm(PostEntity formEntity)
        {
            //字段验重
            if (ValidateExist(formEntity.B_PostId, "B_Name", formEntity.B_Name, formEntity.B_ManaframeId)) return (false, "岗位名称已存在！");
            if (ValidateExist(formEntity.B_PostId, "B_EnCode", formEntity.B_EnCode, formEntity.B_ManaframeId)) return (false, "岗位编号已存在！");
            if (!formEntity.B_PostId.IsEmpty())
            {
                //编辑(Null、主键不会更改)
                formEntity.Modify();
                this.BaseRepository.Update(formEntity);
            }
            else
            {
                //新增
                formEntity.Create();
                this.BaseRepository.Insert(formEntity);
            }
            return (true, "保存成功！");
        }
        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="formEntity"></param>
        [RemoveCache]
        public virtual (bool, string) DeleteForm(PostEntity formEntity)
        {
            this.BaseRepository.Delete(formEntity);
            return (true, "删除成功！");
        }
        /// <summary>
        /// 状态更改
        /// <summary>
        /// <param name="formEntity">数据实体</param>
        /// <returns></returns>
        [RemoveCache]
        public virtual (bool, string) ChangeState(PostEntity formEntity)
        {
            if (!formEntity.B_PostId.IsEmpty())
            {
                this.BaseRepository.Update(new PostEntity() { B_PostId = formEntity.B_PostId, B_EnabledMark = formEntity.B_EnabledMark });
                return (true, "更改成功！");
            }
            else
            {
                return (false, "更改失败！");
            }
        }
        #endregion

        #region 数据验证
        /// <summary>
        /// 验证字段值是否存在
        /// </summary>
        /// <param name="id">实体主键</param>
        /// <param name="field">字段名</param>
        /// <param name="value">字段值</param>
        /// <param name="manaId">架构主键</param>
        /// <returns></returns>
        public bool ValidateExist(string id, string field, string value, string manaId)
        {
            var expression = LinqExtensions.True<PostEntity>();
            if (!string.IsNullOrEmpty(id))
            {
                expression = expression.And(t => t.B_PostId != id);
            }
            if (!string.IsNullOrEmpty(manaId))
            {
                expression = expression.And(t => t.B_ManaframeId == manaId);
            }
            return this.BaseRepository.IQueryable(expression).Exist(field, value);
        }
        #endregion

    }
}
